/**
 * AI API 客户端工具
 * 使用OpenAI SDK进行API调用，支持多种模型提供商
 */

import OpenAI from 'openai';
import { settings } from '../core/settings.ts';

// 定义提供商类型
export type ProviderType = 'deepseek' | 'siliconflow' | 'unknown';

// API端点配置
const API_CONFIG = {
  deepseek: {
    baseURL: 'https://api.deepseek.com',
    apiKeyName: 'deepseek_api_key' as const
  },
  siliconflow: {
    baseURL: 'https://api.siliconflow.cn/v1',
    apiKeyName: 'siliconflow_api_key' as const
  }
};

/**
 * 根据模型名称确定提供商
 * @param model 模型名称
 * @returns 提供商类型
 */
export function determineProvider(model: string): ProviderType {
  const modelLower = model.toLowerCase();
  
  if (modelLower.includes('deepseek')) {
    return 'deepseek';
  } else if (
    modelLower.includes('glm') ||
    modelLower.includes('zhipu') ||
    modelLower.includes('yi') ||
    modelLower.includes('qwen') ||
    modelLower.includes('moonshot') ||
    modelLower.includes('baichuan')
  ) {
    return 'siliconflow';
  }
  
  return 'unknown';
}

/**
 * 获取提供商友好名称
 * @param model 模型名称
 * @returns 友好名称
 */
export function getProviderFriendlyName(model: string): string {
  const modelLower = model.toLowerCase();
  
  if (modelLower.includes('deepseek')) {
    return 'DeepSeek';
  } else if (modelLower.includes('glm') || modelLower.includes('zhipu')) {
    return '智谱GLM';
  } else if (modelLower.includes('yi')) {
    return '零一万物Yi';
  } else if (modelLower.includes('qwen')) {
    return '通义千问';
  } else if (modelLower.includes('moonshot')) {
    return 'Moonshot';
  } else if (modelLower.includes('baichuan')) {
    return '百川';
  }
  
  return '所选AI服务';
}

/**
 * 获取模型的API Client实例
 * @param model 模型名称
 * @returns OpenAI客户端或错误信息
 */
export async function getApiClient(model: string): Promise<{ client: OpenAI, error?: undefined } | { client?: undefined, error: string }> {
  const provider = determineProvider(model);
  
  if (provider === 'unknown') {
    return { error: `不支持的模型: ${model}` };
  }
  
  const config = API_CONFIG[provider];
  const providerName = getProviderFriendlyName(model);
  
  // 获取API密钥
  const apiKey = await settings.get(config.apiKeyName);
  
  if (!apiKey) {
    return { error: `未设置${providerName}的API密钥，请在设置中配置` };
  }
  
  // 创建OpenAI客户端实例
  try {
    const client = new OpenAI({
      baseURL: config.baseURL,
      apiKey: apiKey,
      dangerouslyAllowBrowser: true // 允许在浏览器环境使用
    });
    
    return { client };
  } catch (error) {
    console.error(`创建${providerName}客户端失败:`, error);
    return { error: `无法初始化${providerName}客户端: ${error instanceof Error ? error.message : String(error)}` };
  }
}

/**
 * 处理API错误并返回用户友好信息
 * @param error 错误对象
 * @param model 模型名称
 * @returns 用户友好错误信息
 */
export function handleApiError(error: unknown, model: string): string {
  const providerName = getProviderFriendlyName(model);
  
  if (error instanceof Error) {
    const errorMessage = error.message.toLowerCase();
    
    if (errorMessage.includes('authentication') || errorMessage.includes('api key') || errorMessage.includes('auth')) {
      return `${providerName}的API密钥无效。请在设置中检查并更新您的API密钥。`;
    }
    
    if (errorMessage.includes('permission') || errorMessage.includes('not authorized')) {
      return `您没有使用${providerName}所选模型的权限。请检查您的账户权限或选择其他模型。`;
    }
    
    if (errorMessage.includes('quota') || errorMessage.includes('billing') || errorMessage.includes('rate limit')) {
      return `您的${providerName}账户已超出使用配额或存在计费问题。 可能的解决方法: 1. 检查您的账户余额 2. 更新付款信息 3. 升级您的账户套餐`;
    }
    
    return `${providerName}服务错误: ${error.message}`;
  }
  
  return `${providerName}服务出现未知错误`;
}

/**
 * 直接调用API端点，避开OpenAI SDK的类型限制
 * @param model 模型名称
 * @param messages 消息数组
 * @param options 请求选项
 * @returns API响应
 */
export async function callApiDirectly(
  model: string,
  messages: Array<{role: string, content: string}>,
  options: {
    temperature?: number,
    max_tokens?: number,
    stream?: boolean,
    onChunk?: (chunk: string) => void,
    [key: string]: any
  } = {}
): Promise<any> {
  const provider = determineProvider(model);
  
  if (provider === 'unknown') {
    throw new Error(`不支持的模型: ${model}`);
  }
  
  const config = API_CONFIG[provider];
  const providerName = getProviderFriendlyName(model);
  
  // 获取API密钥
  const apiKey = await settings.get(config.apiKeyName);
  
  if (!apiKey) {
    throw new Error(`未设置${providerName}的API密钥，请在设置中配置`);
  }
  
  // 确保消息格式正确 - 只包含role和content字段
  const cleanedMessages = messages.map(msg => ({
    role: msg.role === 'user' ? 'user' : (msg.role === 'system' ? 'system' : 'assistant'),
    content: typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content)
  }));
  
  // 构建请求体
  const requestBody = {
    model: model,
    messages: cleanedMessages,
    temperature: options.temperature ?? 0.7,
    max_tokens: options.max_tokens ?? 1000,
    stream: !!options.stream,
    ...Object.fromEntries(
      Object.entries(options).filter(([key]) => 
        !['temperature', 'max_tokens', 'stream', 'onChunk'].includes(key)
      )
    )
  };
  
  console.log(`直接调用API: ${config.baseURL}/chat/completions, 模型: ${model}`);
  console.log(`请求体:`, JSON.stringify(requestBody, null, 2).substring(0, 200) + '...');
  
  try {
    // 处理流式响应
    if (options.stream && options.onChunk) {
      console.log('使用流式响应模式');
      
      const response = await fetch(`${config.baseURL}/chat/completions`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Authorization': `Bearer ${apiKey}`
        },
        body: JSON.stringify(requestBody)
      });
      
      if (!response.ok) {
        const errorText = await response.text();
        console.error(`API流式请求失败 [${response.status}]: ${errorText}`);
        throw new Error(`${providerName}服务错误: ${response.status} - ${errorText}`);
      }
      
      if (!response.body) {
        throw new Error('无法获取响应流');
      }
      
      // 处理流式响应
      const reader = response.body.getReader();
      const decoder = new TextDecoder('utf-8');
      let buffer = '';
      let fullResponse = '';
      
      try {
        while (true) {
          const { done, value } = await reader.read();
          
          if (done) break;
          
          // 解码数据块
          const chunk = decoder.decode(value, { stream: true });
          buffer += chunk;
          
          // 处理缓冲区
          const lines = buffer.split('\n');
          // 保留最后一行，可能是不完整的
          buffer = lines.pop() || '';
          
          // 处理每一行
          for (const line of lines) {
            if (line.trim() === '') continue;
            if (line.trim() === 'data: [DONE]') continue;
            
            if (line.startsWith('data: ')) {
              try {
                const jsonStr = line.substring(6);
                const json = JSON.parse(jsonStr);
                
                if (json.choices && json.choices.length > 0) {
                  const delta = json.choices[0].delta;
                  if (delta && delta.content) {
                    // 发送新增内容到回调
                    options.onChunk(delta.content);
                    fullResponse += delta.content;
                  }
                }
              } catch (e) {
                console.warn('解析流式响应行失败:', e, line);
              }
            }
          }
        }
      } catch (streamError) {
        console.error('处理流式响应时发生错误:', streamError);
        throw streamError;
      }
      
      // 构造一个与非流式响应格式相似的对象
      return {
        id: `stream-${Date.now()}`,
        object: 'chat.completion',
        created: Date.now(),
        model: model,
        choices: [{
          index: 0,
          message: {
            role: 'assistant',
            content: fullResponse
          },
          finish_reason: 'stop'
        }],
        usage: {
          prompt_tokens: 0,
          completion_tokens: 0,
          total_tokens: 0
        }
      };
    }
    
    // 非流式响应处理（原有逻辑）
    const response = await fetch(`${config.baseURL}/chat/completions`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${apiKey}`
      },
      body: JSON.stringify(requestBody)
    });
    
    // 获取文本响应
    const responseText = await response.text();
    
    if (!response.ok) {
      console.error(`API请求失败 [${response.status}]: ${responseText}`);
      throw new Error(`${providerName}服务错误: ${response.status} - ${responseText}`);
    }
    
    try {
      // 尝试解析JSON
      const jsonResponse = JSON.parse(responseText);
      
      // 确保响应有正确的结构
      if (!jsonResponse.choices || !Array.isArray(jsonResponse.choices) || jsonResponse.choices.length === 0) {
        console.error('无效的API响应格式:', jsonResponse);
        throw new Error('API返回了意外的响应格式');
      }
      
      // 构造一个与OpenAI响应格式兼容的对象
      return {
        id: jsonResponse.id || '',
        object: jsonResponse.object || 'chat.completion',
        created: jsonResponse.created || Date.now(),
        model: jsonResponse.model || model,
        choices: jsonResponse.choices.map(choice => ({
          index: choice.index || 0,
          message: {
            role: choice.message?.role || 'assistant',
            content: choice.message?.content || ''
          },
          finish_reason: choice.finish_reason || 'stop'
        })),
        usage: jsonResponse.usage || {
          prompt_tokens: 0,
          completion_tokens: 0,
          total_tokens: 0
        }
      };
    } catch (jsonError) {
      console.error('解析JSON响应失败:', jsonError);
      throw new Error(`解析API响应失败: ${jsonError instanceof Error ? jsonError.message : String(jsonError)}`);
    }
  } catch (error) {
    console.error(`调用${providerName} API失败:`, error);
    throw error;
  }
} 